//	折线图
import React from 'react';
import { DualAxes } from '@antv/g2plot';
import { defaultData, MIN_MAX } from './mock';
import { getComponentData } from 'src/services/AnalyseManage';
import { WD_TYPE, DL_TYPE, THEME_COLOR } from 'src/pages/AnalyseManage/EditReport/components/EditorDataType/EnumConfig';
import { ChartService, IProps } from 'src/pages/AnalyseManage/EditReport/components/ChartsType/components/ChartService';
import { CHART_LINK } from 'src/pages/AnalyseManage/EditReport/topics';
import PubSub from 'pubsub-js';
import { isNumber } from 'src/libs/utils';

export default class DoubleYLineChart extends ChartService {
	state = {
		chartEl: null,
		dataLY: defaultData,
		dataRY: defaultData,
		min_max: MIN_MAX,
		eventToken: [],
		dependencies: [],	// 图表联动参数
		isRender: false
	};

	initEvent = async () => {
		const { dataLY, dataRY, min_max } = await this.getConditionData();
		this.setState( {
			dataLY: dataLY,
			dataRY: dataRY,
			min_max: min_max
		}, () => {

			const line = new DualAxes( this.props.id, this.getConfig() );
			line.render();
			this.setState( {
				chartEl: line,
				isRender: true
			} );

			//	数据联动 组装联动参数
			line.on( 'element:click', ( ev ) => {
				if( !this.props.config.mutual.isChainAvailable ) return;

				const intervalElement = ev.target.get( 'element' );
				const data = intervalElement.getModel().data; // 单条数据
				console.log( data );
				if( Object.prototype.toString.call( data ) === '[object Array]' ) return;
				let dimension = [];

				//	取x轴字段和颜色维度字段
				const tempArray = [
					{
						key: 'chartLineXColumns',
						itemKey: 'name'
					},
					{
						key: 'chartLineColorColumns',
						itemKey: 'category'
					}
				];

				tempArray.forEach( field => {
					let columns = this.props.config.data[field.key];
					if( columns && columns.length > 0 ) {
						dimension = dimension.concat( columns.map( ( item, index ) => {
							return {
								formatType: item.formatType,
								id: [ item.name ],
								quota: item.modelType === WD_TYPE ? 'WD' : 'DL',
								symbol: 'EQ',
								value: [ data[field.itemKey] ]		//	从原数据中找到item，一一对应字段
							};
						} ) );
					}
				} );

				if( dimension.length === 0 ) return;

				PubSub.publish( CHART_LINK, {
					publisherId: this.props.id,
					listenerIds: this.props.config.mutual.chartsChainIds,
					dimension: dimension,
					tableCode: this.props.config.data.tableCode
				} );
			} );
		} );
	};

	getSnapshotBeforeUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{ dependencies: any }> ): any | null {
		let { config } = this.props;
		let changeObj = Object.create( null );
		const prevDataConfig = prevProps.config.data, currentDataConfig = config.data;

		//	判断数据字段是否变化了
		if ( JSON.stringify( prevDataConfig.filterFields ) !== JSON.stringify( currentDataConfig.filterFields ) ||
		     JSON.stringify( prevDataConfig.filterConditions ) !== JSON.stringify( currentDataConfig.filterConditions ) ||
			 JSON.stringify( prevDataConfig.chartLineXColumns ) !== JSON.stringify( currentDataConfig.chartLineXColumns ) ||
			 JSON.stringify( prevDataConfig.chartLineLYColumns ) !== JSON.stringify( currentDataConfig.chartLineLYColumns ) ||
			 JSON.stringify( prevDataConfig.chartLineRYColumns ) !== JSON.stringify( currentDataConfig.chartLineRYColumns ) ||
			 JSON.stringify( prevDataConfig.chartLineColorColumns ) !== JSON.stringify( currentDataConfig.chartLineColorColumns ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( prevState.dependencies ) ) {
			changeObj.needDataChange = true;
		}

		//	判断样式是否改变
		if ( JSON.stringify( prevProps.config.style ) !== JSON.stringify( config.style ) ) {
			changeObj.needStyleChange = true;
		}

		//	折线图样式类型
		if ( JSON.stringify( prevDataConfig.chartLineLYColumnsUnit ) !== JSON.stringify( currentDataConfig.chartLineLYColumnsUnit ) || 
		     JSON.stringify( prevDataConfig.chartLineRYColumnsUnit ) !== JSON.stringify( currentDataConfig.chartLineRYColumnsUnit ) ||
		 	 JSON.stringify( prevProps.config.data.lineType ) !== JSON.stringify( config.data.lineType )  ) {
			changeObj.needDataConfigChange = true;
		}

		return changeObj;
	}
	
	shouldComponentUpdate( nextProps: Readonly<IProps>, nextState: Readonly<{ dependencies: any }>, nextContext: any ): boolean {
		if ( JSON.stringify( nextProps ) !== JSON.stringify( this.props ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( nextState.dependencies ) ) return true;
		return false;
	}

	async componentDidUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{}>, snapshot?: any ) {

		if ( snapshot.needStyleChange || snapshot.needDataConfigChange ) {
			this.state.chartEl.update( this.getConfig() );
		}
		if ( snapshot.needDataChange ) {
			// 更新折线图的数据
			const { dataLY, dataRY, min_max } = await this.getConditionData();
			this.setState( {
				dataLY: dataLY,
				dataRY: dataRY,
				MIN_MAX: min_max,
			}, () => {
				// this.state.chartEl.update( this.getConfig() );
				const data = [ dataLY, dataRY ];
				this.state.chartEl.changeData( data );
			} );
		}

	}

	getConfig = (): any => {
		let { style, data: dataConfigs } = this.props.config;

		// const getPadding = ( value: number, type: string ) => {
		// 	if ( style.isShowLegend && style.legendPosition === type ) {
		// 		const defaultValue = type === 'top' ? 0 : 30;
		// 		return value ? value + defaultValue : defaultValue;
		// 	}
		// 	return value ? value : 10;
		// };

		console.log( style.customBlockColorRY );
		return {
			data: [ this.state.dataLY, this.state.dataRY ],
			xField: 'name',
			yField: [ 'value', 'value2' ],
			// 设置轴边距
			appendPadding: [
				style.chartTopPadding || 0,
				style.chartRightPadding || 0,
				style.chartBottomPadding || 0,
				style.chartLeftPadding || 0
			],
			meta: {
				name: {
					alias: style.chartDXAxisName || 'name' ,
				},
				value: {
					alias: style.chartLYAxisName || 'value' ,
					formatter: ( data, v, r ) => {
						return data;
					},
				},
				value2: {
					alias: style.chartRYAxisName || 'value2' ,
					formatter: ( data, v, r ) => {
						return data;
					},
				},
			},
			geometryOptions: [
				{
					seriesField: 'category',
					geometry: 'line',
					color: ( style.customBlockColorLY ? style.customBlockColorLY.map( v => v.color ) : [] ).concat( THEME_COLOR ),
					point: this.getPointOptions( style, dataConfigs ),
					label: this.getDataLabelConfig( style )
				},
				{
					seriesField: 'category',
					geometry: 'line',
					color: ( style.customBlockColorRY ? style.customBlockColorRY.map( v => v.color ) : [] ).concat( THEME_COLOR ),
					point: this.getPointOptions( style, dataConfigs ),
					label: this.getDataLabelConfig( style )
				},
			],

			padding: 'auto',

			legend:
				style.isShowLegend === true
					? {
						position: style.legendPosition,
						itemName: {
							style: {
								fill: style.legendFontColor,
								fontSize: parseInt( style.legendFontSize || 15 ),
								fontFamily: style.legendFontFamily,
								fontWeight: style.legendFontBold ? 'bold' : 'normal',
								fontStyle: style.legendFontItalic ? 'italic' : 'normal',
							},
						},
					  }
					: false,
			tooltip: this.getToolTipConfig( style ),
			xAxis: {
				tickCount: 5,
				line:
					style.isShowDXLine === false
						? null
						: {
							style: {
								stroke: style.chartLineColor,
							},
						  },
				title:
					style.isShowDXLine && style.isShowDXLineName
						? {
							offset: 30,
							style: {
								// offset: 5,
								// textAlign: 'center',
								fontFamily: style.DXLineFontFamily || 'SimSun',
								fontSize: parseInt( style.DXLineFontSize || 15 ),
								fontWeight: style.DXLineFontBold ? 'bold' : 'normal',
								fontStyle: style.DXLineFontItalic ? 'italic' : 'normal',
								fill: style.DXLineFontColor || '#333',
							},
						  }
						: null,
				tickLine: style.isShowDXLine === false ? null : {},
				label: {
					style: style.chartLineDataColor
						? {
							fill: style.chartLineDataColor,
							fontSize: style.isShowDXLine === false ? 0 : 12,
						  }
						: {
							// 设置X轴不显示，设置axis为null不生效，需要设置不显示label, line, tickline
							fontSize: style.isShowDXLine === false ? 0 : 12,
						  },
					rotate: style.chartDXAxisLabelTilt ? style.chartDXAxisLabelTilt : 0,
				},
			},
			yAxis: this.getYAxisCoinfig( style, dataConfigs ),
			interactions: [ { type: 'marker-active' } ],
		};
	};

	getDataLabelConfig = ( style ) => {
		return style.isShowLabelData
			? {
				style: {
					fontFamily: style.labelFontFamily || 'SimSun',
					fontSize: parseInt( style.labeleFontSize || 15 ),
					fontWeight: style.labeleFontBold ? 'bold' : 'normal',
					fontStyle: style.labelFontItalic ? 'italic' : 'normal',
					fill: style.labelFontColor || '#333',
				},
				formatter: ( data, c, d ) => {
					// 设置显示最大最小数据
					// console.log( 'category', this.state.min_max, data );
					let { value, category, precision = '', dataUnit = '' } = data;
					if( !this.state.min_max[category] ) return '';
					let { min = '', max = '' } = this.state.min_max[category];
					if ( style.onlyShowLabelMax && value.toString() === max.toString() ) {
						return `${max}${dataUnit}`;
					} else if ( style.onlyShowLabelMin && value.toString() === min.toString() ) {
						return `${min}${dataUnit}`;
					} else if (
						( style.onlyShowLabelMax && value.toString() !== max.toString() ) ||
							( style.onlyShowLabelMin && value.toString() !== min.toString() )
					) {
						return null;
					} else {
						value = isNumber( precision ) ? value.toFixed( precision ) : value;
						return `${value}${dataUnit}`;
					}
				},
				content: ''
		  }
			: null;
	};

	getYAxisCoinfig = ( style, dataConfigs ) => {
		return [
			// 左Y轴
			{
				line: style.isShowLYLine
					? {
						style: {
							stroke: style.chartLineColor,
						},
					  }
					: null,
				tickLine: style.isShowLYLine === false ? null : {},
				title: style.isShowLYLine && style.isShowLYLineName
					? {
						style: {
							offset: 5,
							// textAlign: 'center',
							fontFamily: style.LYLineFontFamily || 'SimSun',
							fontSize: parseInt( style.LYLineFontSize || 15 ),
							fontWeight: style.LYLineFontBold ? 'bold' : 'normal',
							fontStyle: style.LYLineFontItalic ? 'italic' : 'normal',
							fill: style.LYLineFontColor || '#333',
						},
						autoRotate: true
					  }
					: null,
				// 网格线样式
				grid: style.isHiddenLYGridLine
					? null
					: {
						line: {
							style: {
								stroke: style.chartGridlineColor,
							},
						},
					  },
				// 设置坐标轴文字部分样式
				label: {
					formatter: ( v ) => {
						v = parseFloat( v );
						if( style.chartLYAxisDataUnit === 'percent' ) {
							return `${ v * 100 }%`;
						}
						if( style.chartLYAxisDataUnit === 'tenthousand' ) {
							return `${ v / 10000 }万`;
						}
						if( style.chartLYAxisDataUnit === 'million' ) {
							return `${ v / 1000000 }百万`;
						}
						
						return `${ v }${dataConfigs.chartLineLYColumnsUnit || ''}`;
					},
					style: style.chartLineDataColor
						? {
							fill: style.chartLineDataColor,
							fontSize: style.isShowLYLine === false ? 0 : 12,
						  }
						: {
							// 设置Y轴不显示，设置axis为null不生效，需要设置不显示label, line, tickline
							fontSize: style.isShowLYLine === false ? 0 : 12,
						  },

				},
			},
			// 右Y轴
			{
				line: style.isShowRYLine
					? {
						style: {
							stroke: style.chartLineColor,
						},
					  }
					: null,
				tickLine: style.isShowRYLine === false ? null : {},
				title: style.isShowRYLine && style.isShowRYLineName
					? {
						style: {
							// offset: 5,
							// textAlign: 'center',
							fontFamily: style.RYLineFontFamily || 'SimSun',
							fontSize: parseInt( style.RYLineFontSize || 15 ),
							fontWeight: style.RYLineFontBold ? 'bold' : 'normal',
							fontStyle: style.RYLineFontItalic ? 'italic' : 'normal',
							fill: style.RYLineFontColor || '#333',
						},
					  }
					: null,
				// 设置坐标轴文字部分样式
				label: {
					formatter: ( v ) => {
						v = parseFloat( v );

						if( style.chartRYAxisDataUnit === 'percent' ) {
							return `${ v * 100 }%`;
						}
						if( style.chartRYAxisDataUnit === 'tenthousand' ) {
							return `${ v / 10000 }万`;
						}
						if( style.chartRYAxisDataUnit === 'million' ) {
							return `${ v / 1000000 }百万`;
						}
						return `${ v }${dataConfigs.chartLineRYColumnsUnit || ''}`;
					},
					style: style.chartLineDataColor
						? {
							fill: style.chartLineDataColor,
							fontSize: style.isShowRYLine === false ? 0 : 12,
						}
						: {
							// 设置Y轴不显示，设置axis为null不生效，需要设置不显示label, line, tickline
							fontSize: style.isShowRYLine === false ? 0 : 12,
						},

				},
			},
		];
	};
	// 设置数据单位
	getDataByDataUnit = ( category, value, type, precision = '', dataUnit = '' ) => {
		value = isNumber( precision ) ? value.toFixed( precision ) : value;

		return {
			name: category,
			value: `${value}${dataUnit}`
		};
	};

	// 设置提示config
	getToolTipConfig = ( style ) => {

		const _this = this;

		return style.isShowToolTip
			? {
				shared: true,
				// 设置toolTip相关样式
				domStyles: {
					'g2-tooltip-list-item': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor,
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
					'g2-tooltip-title': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor,
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
				},

				showCrosshairs: true,
				crosshairs: {
					line: {
						style: {
							stroke: style.chartHoverLineColor || 'rgba(33,33,33, 0.5)'
						}
					}
				},
				fields: [ 'category', 'name', 'value', 'value2', 'precision', 'dataUnit' ],
				formatter: ( data ) => {
					if( data.value ) {
						// 左Y轴
						return _this.getDataByDataUnit( data.category, data.value, 'LY', data.precision, data.dataUnit );
					}
					if( data.value2 ) {
						// 右Y轴
						return _this.getDataByDataUnit( data.category, data.value2, 'RY', data.precision, data.dataUnit );
					}
				}
			  }
			: {
				showMarkers: false,
				showContent: false,
				domStyles: null,
				follow: false,
			  };
	};

	// 设置标签样式
	getPointOptions = ( style, dataConfig ) => {
		let config = {
			size: style.chartLabelMarkSize || 5,
			shape: style.chartLabelMarkType
				? style.chartLabelMarkType === 'hollowCircle'
					? 'hollow-circle'
					: style.chartLabelMarkType
				: 'circle',
			style: {
				fill: '',
				stroke: '',
				lineWidth: 0,
				fillOpacity: dataConfig.lineType === 'basic' ? 0 : 1
			},
		};
		// 如果是空心圆需要填充白色
		if ( style.chartLabelMarkType === 'hollowCircle' ) {
			config.style.fill = 'white';
			config.style.lineWidth = 2;
		}
		// if( dataConfig.lineType === 'basic' ) return null;
		
		// return style.isShowLabelData || dataConfig.lineType === 'dataPoints' ? config : null;
		return config;
	};

	// 获取折线图的数据
	async getConditionData() {
		const { data: dataConfigs } = this.props.config;
		if (
			dataConfigs.chartLineXColumns &&
			dataConfigs.chartLineXColumns.length > 0 &&
			( ( dataConfigs.chartLineLYColumns && dataConfigs.chartLineLYColumns.length > 0 ) ||
				( dataConfigs.chartLineRYColumns && dataConfigs.chartLineRYColumns.length > 0 ) )
		) {
			const itemInfo = ( v, orderType?, desc? ) => {
				return {
					aggregateType: v.modelType === DL_TYPE ? v.aggregateType : '', //	度量的聚合类型
					formatType: v.modelType === WD_TYPE ? v.formatType : '', // 维度的聚合类型v.
					alias: v.title.trim(),
					dataType: v.dataType,
					frontendId: '',
					id: v.name,
					orderType: v.modelType === DL_TYPE && !v.orderType ? 'ASC' : v.orderType, // 排序方式
					quota: v.modelType === WD_TYPE ? 'WD' : 'DL',
					symbol: '',
					type: v.type,
					value: '',
					dataUnit: v.dataUnit || '',
					precision: v.precision
				};
			};
			
			const x = dataConfigs.chartLineXColumns.map( ( v ) => {
				return itemInfo( v );
			} );

			const y = dataConfigs.chartLineLYColumns ? dataConfigs.chartLineLYColumns.map( ( v ) => {
				return itemInfo( v );
			} ) : [];
			const y2Columns = dataConfigs.chartLineRYColumns ? dataConfigs.chartLineRYColumns.map( ( v ) => {
				return itemInfo( v );
			} ) : [];

			const category = dataConfigs.chartLineColorColumns
				? dataConfigs.chartLineColorColumns.map( ( v ) => {
					return itemInfo( v );
				  } )
				: [];

			// 内部筛选 condition
			const filterFieldCondition = this.props.config.data.filterFields
				? this.props.config.data.filterFields.map( ( v ) => v.filterConditions ).flat()
				: [];

			// 筛选组件的 condition
			let filterCompConditions = this.props.config.data.filterConditions || {};
			let newFilterCompConditions = [];
			Object.keys( filterCompConditions ).forEach( ( key ) => {
				newFilterCompConditions = newFilterCompConditions.concat( filterCompConditions[key] );
			} );
			
			const request = {
				dataConfig: {
					dataModel: {
						pageId: this.props.pageId,
						tableName: this.props.config.data.tableCode,
						x: x,
						y: y,
						y2: y2Columns,
						category: category,
						conditions: filterFieldCondition.concat( this.state.dependencies, newFilterCompConditions )
					},
					needAutoRefresh: true,
					tableType: 'double',
				},
				type: 'line',
				tenantCode: this.props.tenantCode
			};

			let pageResponse = await getComponentData( request );
			if ( pageResponse.data && pageResponse.data.success ) {
				let { rows = [], y2 = [], extra } = pageResponse.data.data;
			
				// const newRows = transformDataUnitData( rows, y, 'value' );
				// const newY2 = transformDataUnitData( y2, y2Columns, 'value2', 'value' );

				// console.log( newRows,newY2 );
				const newY2 = y2.map( v => {
					return {
						...v,
						value2: v.value
					};
				} );
				
				return { dataLY: rows, dataRY: newY2, min_max: extra.maxmin };
			}
		}

		return { dataLY: defaultData, dataRY: defaultData, min_max: MIN_MAX };
	}

	render() {
		return <div id={this.props.id} style={{ height: '100%' }}></div>;
	}
}
